use std::cell::RefCell;
use std::collections::HashMap;
use std::fs::{File, OpenOptions};
use std::io::{BufRead, BufReader, Write};
use std::rc::Rc;

#[derive(Clone)]
pub struct KVdbEmu {
    file: Rc<RefCell<File>>,
    data: HashMap<Vec<u8>, Vec<u8>>,
}

impl KVdbEmu {
    pub fn new() -> KVdbEmu {
        let file = OpenOptions::new().create(true).read(true).write(true).append(true).open("./bcdb.txt").unwrap();

        let reader = BufReader::new(&file);
        let mut data = HashMap::new();

        for line in reader.lines() {
            let line = line.unwrap();
            let (key, value) = line.split_once(" ").unwrap();
            data.insert(serde_json::from_str(key).unwrap(), serde_json::from_str(value).unwrap());
            // println!("key={}, value={}", key, value);
        }

        let db = KVdbEmu {
            file: Rc::new(RefCell::new(file)),
            data,
        };

        db
    }

    pub fn get(&self, key: &Vec<u8>) -> Option<Vec<u8>> {
        self.data.get(key).cloned()
    }

    pub fn put(&mut self, key: &Vec<u8>, value: &Vec<u8>) {
        self.data.insert(key.clone(), value.clone());
        self.file.borrow_mut().write((serde_json::to_string(key).unwrap() + " " + serde_json::to_string(value).unwrap().as_str() + "\n").as_bytes()).expect("panic");
    }
}